#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

#define DEFAULT_BUFLEN 512  // 缓冲区大小

int main() 
{
    /* 初始化 Winsock */
    WSADATA wsaData;
    int iResult;

    // 调用 WSAStartup 函数以启用 WS2_32.dll 库
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if(iResult != 0)
    {
        std::cout << "WSAStartup failed: " << iResult << std::endl;
        return 1;
    }

    /* 创建套接字 */
    SOCKET serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(serverSocket == INVALID_SOCKET)
    {
        std::cout << "create socket failed with error: " << WSAGetLastError() << std::endl;
        WSACleanup();
        return 1;
    }

    /* 绑定套接字 */
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET; // IPv4 地址族
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 监听所有可用的 IP 地址 or INADDR_ANY
    serverAddr.sin_port = htons(27015); // 监听的端口号

    iResult = bind(serverSocket, (sockaddr*)&serverAddr, sizeof(serverAddr));
    if(iResult == SOCKET_ERROR)
    {
        std::cout << "bind failed with error: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }

    /* 接收数据 */
    sockaddr_in clientAddr;
    int clientAddrLen = sizeof(clientAddr);
    char recvBuffer[1024];
    iResult = recvfrom(serverSocket, recvBuffer, sizeof(recvBuffer), 0, (sockaddr*)&clientAddr, &clientAddrLen);
    if(iResult > 0)
    {
        std::cout << "bytes received: " << iResult << std::endl;
        std::cout << "received message: " << recvBuffer << std::endl;

        /* 发送数据 */
        // 回显到客户端
        recvBuffer[iResult] = ' ';
        recvBuffer[iResult+1] = '-';
        recvBuffer[iResult+2] = '>';
        recvBuffer[iResult+3] = ' ';
        recvBuffer[iResult+4] = 'E';
        recvBuffer[iResult+5] = 'C';
        recvBuffer[iResult+6] = 'H';
        recvBuffer[iResult+7] = 'O';
        recvBuffer[iResult+8] = '\0';
        iResult = sendto(serverSocket, recvBuffer, iResult+9, 0, (sockaddr*)&clientAddr, clientAddrLen);
        if(iResult > 0)
        {
            std::cout << "server: sent " << iResult << " bytes of data" << std::endl;
        }
        else
        {
            std::cout << "sendto failed with error: " << WSAGetLastError() << std::endl;
            closesocket(serverSocket);
            WSACleanup();
            return 1;
        }
    }
    else if(iResult == 0)
    {
        std::cout << "connection closed" << std::endl;
    }
    else
    {
        std::cout << "recvfrom failed with error: " << WSAGetLastError() << std::endl;
        closesocket(serverSocket);
        WSACleanup();
        return 1;
    }



    /* 关闭套接字 */
    closesocket(serverSocket);
    // 清理
    WSACleanup();

    std::cout << "server: bye"<< std::endl;
    return 0;
}